package com.fingard.util;

import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import org.bouncycastle.openpgp.*;

import java.io.*;

public class GPGUtil {

    /**
     * GPG签名并加密
     * @param encryFilePath
     * @param resultFilePath
     * @param charset
     * @return
     * @throws Exception
     */
    public static boolean pgpEncryptSigned(String bankPubFilePath,String orgPrvFilePath
            ,char[] passwd,String encryFilePath,String resultFilePath,String charset){
        try {
            //待加密内容
            String data=FileHelper.readFileText(encryFilePath,charset);
            //银行公钥
            PGPPublicKey dbsPubKey = BouncyCastlePgpHelper.readPublicKey(new FileInputStream(bankPubFilePath));
            //客户私钥
            PGPSecretKey glpSecretKey = BouncyCastlePgpHelper.readSecretKey(new FileInputStream(orgPrvFilePath));
            PGPPrivateKey glpPrivateKey = BouncyCastlePgpHelper.findPrivateKey(new FileInputStream(orgPrvFilePath), passwd);
            //加密
            String encryptContent= BouncyCastlePgpHelper.encryptSigned(data, dbsPubKey, glpSecretKey, glpPrivateKey);
            //写入文件
            FileHelper.writeFile(resultFilePath,encryptContent,charset);
            //判断解密结果
            if(StringHelper.hasAnyChar(FileHelper.readFileText(resultFilePath,charset))){
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * GPG仅公钥加密
     * @param encryFilePath
     * @param resultFilePath
     * @return
     * @throws Exception
     */
    public static boolean pgpEncryptWithoutSigned(String bankPubFilePath,String encryFilePath,String resultFilePath,String charset){
        try {
            //银行公钥
            PGPPublicKey dbsPubKey = BouncyCastlePgpHelper.readPublicKey(new FileInputStream(bankPubFilePath));
            //加密并写入文件
            BouncyCastlePgpHelper.encryptWithoutSigned(encryFilePath,resultFilePath, dbsPubKey);
            //判断加密结果
            if(StringHelper.hasAnyChar(FileHelper.readFileText(resultFilePath,charset))){
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * GPG解密
     * @param bankPubFilePath
     * @param orgPrvFilePath
     * @param passwd
     * @param decryptFilePath
     * @param resultFilePath
     * @param charset
     * @return
     */
    public static boolean pgpDecryptAndVerify(String bankPubFilePath,String orgPrvFilePath
            ,char[] passwd,String decryptFilePath,String resultFilePath,String charset){
        try {
            BouncyCastlePgpHelper.decryptFile(bankPubFilePath,orgPrvFilePath,passwd,decryptFilePath,resultFilePath);
            //判断解密结果
            if (StringHelper.hasAnyChar(FileHelper.readFileText(resultFilePath, charset))) {
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 不加签GPG解密
     * @param bankPubFilePath
     * @param orgPrvFilePath
     * @param passwd
     * @param decryptFilePath
     * @param resultFilePath
     * @param charset
     * @return
     */
    public static boolean pgpDecryptWithoutVerify(String orgPrvFilePath
            ,char[] passwd,String decryptFilePath,String resultFilePath,String charset){
        try {
            BouncyCastlePgpHelper.decryptFile(orgPrvFilePath,passwd,decryptFilePath,resultFilePath);
            //判断解密结果
            if (StringHelper.hasAnyChar(FileHelper.readFileText(resultFilePath, charset))) {
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * gpg加密加签cmd命令
     * @param fileName：原文件路径
     * @param encryFileName：加密加签后的文件路径
     * @param bankPubKeyId 银行公钥
     * @param coPrvKeyId 企业私钥
     * @param coPriKeyPsword 企业私钥密码
     * @return
     */
    public static boolean encrypAndSignCmdRun(String fileName,String encryFileName,String bankPubKeyId,String coPrvKeyId,String coPriKeyPsword){
        try{
            StringBuilder command=new StringBuilder("gpg --armor");//cmd命令
            if(hasAnyChar(bankPubKeyId)){
                command.append(" -r "+bankPubKeyId+" ");
            }
            if(hasAnyChar(coPrvKeyId) && !hasAnyChar(coPriKeyPsword)){
                command.append(" --sign --local-user "+coPrvKeyId+" ");
            }
            if(hasAnyChar(coPrvKeyId) && hasAnyChar(coPriKeyPsword)){
                command.append(" --sign --local-user "+coPrvKeyId+" --passphrase "+coPriKeyPsword+" ");
            }
            command.append(" -o "+encryFileName+" -e "+fileName);
            System.out.println(command.toString());
            runCmd(command.toString());
            //Runtime.getRuntime().exec(command.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
        return FileHelper.existFile(encryFileName);
    }

    /**
     * gpg解密cmd命令(验签未加，后续有需要可完善)
     * @param fileName：原文件路径
     * @param decryptFileName：解密后的文件路径
     * @param coPrvKeyId 企业私钥
     * @param coPriKeyPsword 企业私钥密码
     * @return
     */
    public static boolean decryptCmdRun(String fileName,String decryptFileName,String coPrvKeyId,String coPriKeyPsword){
        try{
            StringBuilder command=new StringBuilder("gpg --armor");//cmd命令
            if(hasAnyChar(coPrvKeyId)){
                command.append(" --local-user "+coPrvKeyId+" ");
            }
            if(hasAnyChar(coPrvKeyId) && hasAnyChar(coPriKeyPsword)){
                command.append(" --passphrase "+coPriKeyPsword+" ");
            }
            command.append(" -o "+decryptFileName+" -d "+fileName);
            System.out.println(command.toString());
            runCmd(command.toString());
            //Runtime.getRuntime().exec(command.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
        return FileHelper.existFile(decryptFileName);
    }

    //非空
    private static boolean hasAnyChar(String p_str) {
        if (p_str != null && p_str.length() > 0) {
            return true;
        }
        return false;
    }

    /**CMD命令*/
    private static boolean runCmd(String cmd){
        String retCmdResult = "";
        BufferedReader bufferedReader = null;
        try {
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec(cmd);
            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String readLine;
            while ((readLine = bufferedReader.readLine()) != null) {
                retCmdResult = readLine;
            }
            process.destroy();
            return true;
        } catch (Exception ex) {
            return false;
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /*public static void main(String[] args) {
        String fileName="D:\\HSBCFile\\PayFile\\20190710\\HK190710_TT_v3_710115449409.txt";//待处理文件
        String bankPubKeyId = "6BE01E5D";//银行公钥
        String coPriKeyId = "";//企业私钥
        String coPriKeyPsword= "";//企业私钥密码
        coPriKeyId="B5271175";
        coPriKeyPsword="Citic123";
        //加密
        System.out.println(encrypAndSignCmdRun(fileName, fileName.replace(".txt", ".pgp"), bankPubKeyId, coPriKeyId, coPriKeyPsword));
        //解密
        //System.out.println(decryptCmdRun(fileName.replace(".txt",".pgp"),fileName.replace(".txt",""),coPriKeyId,coPriKeyPsword));
        //加密加签
        //System.out.println(encrypAndSignCmdRun(fileName, fileName.replace(".txt", ".pgp"), bankPubKeyId, coPriKeyId, coPriKeyPsword));
    }*/
}
